package me.haeger.assembler;

/**
 *
 * @author Häger
 */
public class Instruction {
    private int op, rD, rA, rB, k;
    
    private final int OP_LENGTH = 7;
    private final int rX_LENGTH = 5;
    private final int K_LENGTH = 10;
    
    
    public Instruction() {
        op = 0;
        rD = 0;
        rA = 0;
        rB = 0;
        k = 0;
        
    }

    public String print() {
        return getBinOp() + getBinrD() + getBinrA() + getBinrB() + getBinK();
    }
    
    public String easyPrint() {
        return "(" + "(" + "\"" + getBinOp().substring(0, 2) + "\"" + ", "
                + "'" + getBinOp().charAt(2) + "'" + ", " + "'" + getBinOp().charAt(3)+ "'" + ", "
                + "'" + getBinOp().charAt(4) + "'" + ", " + "'" + getBinOp().charAt(5)+ "'" + ", "
                + "'" + getBinOp().charAt(6) + "'" + ")" + ", "
                + "\"" + getBinrD() + "\"" + ", "  + "\"" + getBinrA() + "\"" + ", "
                + "\"" + getBinrB() + "\"" + ", "  + "\"" + getBinK() + "\"" + ")" + ",";
    }
    
    /**
     * @return the op
     */
    public int getOp() {
        return op;
    }
    
    public String getBinOp() {
        return makeBinaryString(op, OP_LENGTH);
    }

    /**
     * @param op the op to set
     */
    public void setOp(int op) throws IllegalArgumentException {
        if(op > (Math.pow(2, OP_LENGTH) - 1))
            throw new IllegalArgumentException("Input out of range.");
        
        this.op = op;
    }

    /**
     * @return the rD
     */
    public int getrD() {
        return rD;
    }

    public String getBinrD() {
        return makeBinaryString(rD, rX_LENGTH);
    }
    
    /**
     * @param rD the rD to set
     */
    public void setrD(int rD) throws IllegalArgumentException {
        if(rD > (Math.pow(2, rX_LENGTH) - 1))
            throw new IllegalArgumentException("Input out of range.");
        
        this.rD = rD;
    }

    /**
     * @return the rA
     */
    public int getrA() {
        return rA;
    }
    
    public String getBinrA() {
        return makeBinaryString(rA, rX_LENGTH);
    }

    /**
     * @param rA the rA to set
     */
    public void setrA(int rA) throws IllegalArgumentException {
        if(rA > (Math.pow(2, rX_LENGTH) - 1))
            throw new IllegalArgumentException("Input out of range.");
        
        this.rA = rA;
    }

    /**
     * @return the rB
     */
    public int getrB() {
        return rB;
    }
    
    public String getBinrB() {
        return makeBinaryString(rB, rX_LENGTH);
    }

    /**
     * @param rB the rB to set
     */
    public void setrB(int rB) throws IllegalArgumentException {
        if(rB > (Math.pow(2, K_LENGTH) - 1))
            throw new IllegalArgumentException("Input out of range.");
        
        this.rB = rB;
    }

    /**
     * @return the k
     */
    public int getK() {
        return k;
    }
    
    public String getBinK() {
        return makeBinaryString(k, K_LENGTH);
    }

    /**
     * @param k the k to set
     */
    public void setK(int k) throws IllegalArgumentException {
        if(k > (Math.pow(2, K_LENGTH) - 1))
            throw new IllegalArgumentException("Input out of range.");
        
        this.k = k;
    }
    
    public String makeBinaryString(int value, int length) {
        
        if(value < 0) {
            return Integer.toBinaryString(value).substring(32 - length);
        }        

        StringBuilder extension = new StringBuilder();
        for(int i = 0 ; i < length - Integer.toBinaryString(value).length() ; i++) {
            extension.append('0');
        }
        return extension.append(Integer.toBinaryString(value)).toString();
    }    
}
